package com.ayu.shortlink.distribute.mq.consumer;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSON;
import com.ayu.shortlink.distribute.common.constant.RocketMQConstant;
import com.ayu.shortlink.distribute.common.convention.exception.ClientException;
import com.ayu.shortlink.distribute.common.convention.exception.RemoteException;
import com.ayu.shortlink.distribute.common.convention.result.Result;
import com.ayu.shortlink.distribute.common.enums.CouponTaskStatusEnum;
import com.ayu.shortlink.distribute.common.enums.CouponTemplateStatusEnum;
import com.ayu.shortlink.distribute.dao.entity.CouponTaskDO;
import com.ayu.shortlink.distribute.dao.entity.CouponTemplateDO;
import com.ayu.shortlink.distribute.dao.mapper.CouponTaskMapper;
import com.ayu.shortlink.distribute.idempotent.MQIdempotentUtil;
import com.ayu.shortlink.distribute.mq.basics.base.MessageWrapper;
import com.ayu.shortlink.distribute.mq.basics.event.CouponTaskExecuteEvent;
import com.ayu.shortlink.distribute.mq.handler.excel.CouponExcelObject;
import com.ayu.shortlink.distribute.mq.handler.excel.ExcelExecutorTaskListener;
import com.ayu.shortlink.distribute.mq.producer.CouponTaskActuallyDistributeProducer;
import com.ayu.shortlink.distribute.remote.dto.IAdminService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

/**
 * 执行优惠券任务的消费者 - 主要功能是读取excel表数据（类似于一个中转站吧）
 */
@Component
@RequiredArgsConstructor
@Slf4j
@RocketMQMessageListener(
        topic = RocketMQConstant.TOPIC_EXECUTOR_IMMEDIATELY_TASK,
        consumerGroup = RocketMQConstant.GROUP_EXECUTOR_IMMEDIATELY_TASK
)
public class CouponTaskExecuteConsumer implements RocketMQListener<MessageWrapper<CouponTaskExecuteEvent>> {
    private final CouponTaskMapper couponTaskMapper;
    private final StringRedisTemplate stringRedisTemplate;
    private final CouponTaskActuallyDistributeProducer couponTaskActuallyDistributeProducer;
    private final MQIdempotentUtil mqIdempotentUtil;
    private final IAdminService iAdminService;

    @Override
    public void onMessage(MessageWrapper<CouponTaskExecuteEvent> messageWrapper) {
        //TODO 保证消费的幂等性
        CouponTaskExecuteEvent message = messageWrapper.getMessage();
        if (mqIdempotentUtil.isMessageBeingConsumed(messageWrapper.getUuid())){
            log.info("幂等消费：已经消费过");
            return;
        }
        log.info("执行优惠券任务的消费者正在消费:{}", JSON.toJSONString(messageWrapper));

        String couponTaskId = String.valueOf(message.getCouponTaskId());
        if(StrUtil.isEmpty(couponTaskId)){
            throw new ClientException("该任务不存在");
        }
        //首先要通过任务的id去搜索优惠券模版的Id
        CouponTaskDO couponTaskDO = couponTaskMapper.selectById(couponTaskId);
        //判断优惠券模板发送状态是否为执行中，如果不是有可能是被取消状态
        if (ObjectUtil.notEqual(couponTaskDO.getStatus(), CouponTaskStatusEnum.IN_PROGRESS.getStatus())) {
            log.warn("[消费者] 优惠券推送任务正式执行 - 推送任务记录状态异常：{}，已终止推送", couponTaskDO.getStatus());
            return;
        }

        Result<CouponTemplateDO> couponTemplate = iAdminService.findCouponTemplateById(
                couponTaskDO.getShopNumber().toString(),
                couponTaskDO.getCouponTemplateId().toString());
        if (couponTemplate == null){
            log.warn("[消费者] 优惠券推送任务正式执行 - 调用引擎服务层失败，将会重试调用");
            throw new RemoteException("调用admin服务层优惠券模板返回空");
        }

        //判断优惠券状态是否正确
        if (ObjectUtil.notEqual(couponTemplate.getData().getStatus(), CouponTemplateStatusEnum.ACTIVE.getStatus())){
            log.error("[消费者] 优惠券推送任务正式执行 - 优惠券ID：{}，优惠券模板状态：{}", couponTemplate.getData().getId(), couponTemplate.getData().getStatus());
            return;
        }

        ExcelExecutorTaskListener excelExecutorTaskListener = new ExcelExecutorTaskListener(stringRedisTemplate, couponTaskDO, couponTaskActuallyDistributeProducer,couponTemplate.getData());
        //进行读取
        //需要指定读取的类型
        EasyExcel.read(couponTaskDO.getFileAddress(), CouponExcelObject.class,excelExecutorTaskListener).sheet().doRead();
        //设置消费完成
        mqIdempotentUtil.setAccomplish(messageWrapper.getUuid());
    }
}
